package gnss_plugs

import (
	"dgo/go-plugs/gnssio"
	"dgo/goutils/gnss"
	"dgo/goutils/utils"
	"strings"
	"time"
)

type NripAnalyzer struct {
	id              string
	FristRecv       string
	ResultCode      int
	IsStop          bool
	NoMountPoint    bool
	ConnectedCnt    int
	Step            int
	IsRtcm          bool
	AuthOk          bool
	RecvSize        int
	StartTime       time.Time
	rtcmraw         *gnss.Rtcm3RawBuf
	inner_data_comm gnssio.I_Comm
}

func NewNtripAnalyzer() *NripAnalyzer {
	rval := &NripAnalyzer{
		rtcmraw: gnss.NewRtcm32RawBuf(""),
	}
	return rval
}

func (this *NripAnalyzer) SetInnerDataComm(data_comm gnssio.I_Comm) {
	if this.inner_data_comm != data_comm {
		if this.inner_data_comm != nil {
			this.inner_data_comm.RemoveListener(this)
		}
		this.inner_data_comm = data_comm
		this.inner_data_comm.AddListener(this)
	}
}

func (this *NripAnalyzer) OnReceive(sender gnssio.I_Comm, buf []byte, l int) {
	if this.Step == 1 {
		if l > 1024 {
			this.FristRecv = utils.Trim(string(buf[:1024]))
		} else {
			this.FristRecv = utils.Trim(string(buf[:l]))
		}
		s := strings.ToUpper(this.FristRecv)
		this.Step = 2 // Step
		if strings.Index(s, "ICY 200 OK") != -1 {
			this.ResultCode = 2
			this.AuthOk = true
			return
		} else if strings.Index(s, "SOURCETABLE") != -1 {
			this.ResultCode = 3
			this.NoMountPoint = true
			go this.Stop()
		} else {
			this.ResultCode = 4
			this.AuthOk = false
			go this.Stop()
		}
	}

	this.RecvSize += l

	for i := 0; i < l; i++ {
		r := this.rtcmraw.InputBuf(buf[i])
		if r == 1 {
			this.IsRtcm = true
			this.rtcmraw.Reset()
		} else if r == -2 {
			this.rtcmraw.Reset()
		} else if r == gnss.RTCM_ERROR_DATA {
			this.rtcmraw.Reset()
		}
	}
}

func (this *NripAnalyzer) OnConnect(sender gnssio.I_Comm) {
	this.Step = 1
	this.ConnectedCnt++
	this.RecvSize = 0
	this.ResultCode = 0
}

func (this *NripAnalyzer) OnDisconnect(sender gnssio.I_Comm) {
	this.Step = 0
}

// =================================================================
func (this *NripAnalyzer) Start() {
	this.inner_data_comm.Start()
	this.StartTime = time.Now()
}

func (this *NripAnalyzer) Stop() {
	this.inner_data_comm.Stop()
	this.IsStop = true
}
